﻿#pragma once

#include "AngelScriptBinder.h"
#include "EffectManager.h"
#include "OverlayManager.h"
#include "..\3rdLib\Ogitor\Ogitors.h"

#include "DebugAssert.h"

_NAMESPACE_BEGIN

/// 启动配置描述结构
struct ConfigDesc
{
	ConfigDesc()
	{
		SetDefault();
		ReadCfgFile();
	}

	~ConfigDesc()
	{
	}

	/// 设置成默认值
	void SetDefault();

	/// 设置当前配置
	void SetConfig(RenderSystem *rSys);

	/// 读取配置文件
	void ReadCfgFile();

	/// 键值分别为配置名和内容的哈希表
	hash_map<string,string> configs;

	/// 配置文件对象
	BECode cfgFile;
};

/// 供脚本和全局使用的OGRE属性
class OgreProperty
{
public:

	/// 单体类声明
	SINGLETON_HELPER(OgreProperty)

	/// 默认构造
	OgreProperty();

	virtual ~OgreProperty();

public:
	/// 设置天空盒
	/// \param[in] enable 使用或关闭
	/// \param[in] name 资源名
	void SetSkyBox(bool enable, CONST_REF(string) name);

	/// 设置Ogre的地形
	/// \param[in] name 地形的配置文件名
	void SetOgreTerrain(CONST_REF(string) name);

	/// 销毁ogitor的场景
	void DestoryOgtScene();

	/// 加载场景
	/// \param[in] name 场景文件的路径
	void LoadOgtScene(CONST_REF(string) name);

	/// 获取Ogitor场景的节点
	/// \param[in] type ogitor的对象(编辑器)类型名
	/// \param[in] name ogitor的物体名
	/// \return Ogre的场景节点指针
	SceneNode* GetOgtNode(CONST_REF(string)type, CONST_REF(string)name);

	/// 编译ogre脚本
	/// \param[in] code 脚本代码
	void	CompileScript(CONST_REF(string)code);

	/// 编译ogreOverlay脚本
	/// \param[in] code 脚本代码
	void	CompileOverlayScript(CONST_REF(string)code);

	/// 设置读取场景时的加载场景
	void setLoadingScene();

	/// 获取节点位置
	/// \param[in] node 节点指针
	/// \param[out] out 节点的位置坐标
	void GetNodePos(SceneNode* node , Vector3& out);

	/// 获取Ogitor场景某节点位置
	/// \param[in] type ogitor的对象(编辑器)类型名
	/// \param[in] name ogitor的物体名
	/// \param[out] out 节点的位置坐标
	void GetOgtNodePos(CONST_REF(string)type,CONST_REF(string)name,Vector3&out);

public:
	///根对象
	Ogre::Root *root;

	/// 渲染窗口
	Ogre::RenderWindow* window;

	/// 游戏场景的场景管理器
	Ogre::SceneManager* sceneManager;		

	/// Ogre启动配置描述结构
	ConfigDesc configDesc;

	///Ogitor根对象
	Ogitors::OgitorsRoot* ogRoot;
	
	///脚本编译器
	Ogre::ScriptCompiler* compiler;

};

/// Ogre渲染系统绑定类
class RenderLib_ScriptBinder
{
public:
	
	/// 单体类声明
	SINGLETON_HELPER(RenderLib_ScriptBinder);

	/// 构造
	RenderLib_ScriptBinder();

	/// 绑定Vector3类
	int Bind_Vector3(asIScriptEngine* engine );

	/// 绑定Ogre的部分内部类
	int Bind_OgreProperty(asIScriptEngine* engine );
protected:
private:
};

REGISTER_TYPEMETHODS(RenderWindow)
{
	
}

REGISTER_TYPEMETHODS(SceneManager)
{

}

REGISTER_TYPEMETHODS(SceneNode)
{
	r = engine->RegisterObjectMethod(type,"void setVisible(bool,bool)",asMETHOD(T,setVisible),asCALL_THISCALL);	 assert( r >= 0 );		
}

REGISTER_TYPEMETHODS(OgreProperty)
{
	r = engine->RegisterObjectProperty(type, "RenderWindow@ window",offsetof(T,window)); assert( r >= 0 );	
	r = engine->RegisterObjectProperty(type, "SceneManager@ sceneManager",offsetof(T,sceneManager)); assert( r >= 0 );	
	r = engine->RegisterObjectProperty(type, "ConfigDesc configDesc",offsetof(T,configDesc)); assert( r >= 0 );	

	r = engine->RegisterObjectMethod
		(type,"void SetSkyBox(bool,const string&in)",asMETHOD(T,SetSkyBox),asCALL_THISCALL);	 assert( r >= 0 );				
	r = engine->RegisterObjectMethod
		(type,"void SetOgreTerrain(const string&in)",asMETHOD(T,SetOgreTerrain),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod
		(type,"void DestoryOgtScene()",asMETHOD(T,DestoryOgtScene),asCALL_THISCALL);	 assert( r >= 0 );				
	r = engine->RegisterObjectMethod
		(type,"void LoadOgtScene(const string&in)",asMETHOD(T,LoadOgtScene),asCALL_THISCALL);	 assert( r >= 0 );				
	r = engine->RegisterObjectMethod
		(type,"SceneNode@ GetOgtNode(const string&in,const string&in)",asMETHOD(T,GetOgtNode),asCALL_THISCALL);	 assert( r >= 0 )

	r = engine->RegisterObjectMethod
		(type,"void CompileScript(const string&in)",
			asMETHOD(T,CompileScript),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod
		(type,"void CompileOverlayScript(const string&in)",
		asMETHOD(T,CompileOverlayScript),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod
		(type,"void GetNodePos(SceneNode@,Vector3&out)",
		asMETHOD(T,GetNodePos),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod
		(type,"void GetOgtNodePos(const string&in,const string&in,Vector3&out)",
		asMETHOD(T,GetOgtNodePos),asCALL_THISCALL);	 assert( r >= 0 );
}

REGISTER_TYPEMETHODS(OverlayMng)
{
	r = engine->RegisterObjectMethod(type,"void SetMaterial(const string&in,const string&in)",asMETHOD(T,SetMaterial),asCALL_THISCALL);	 assert( r >= 0 );							
}


REGISTER_TYPEMETHODS(EffectManager)
{
	r = engine->RegisterObjectMethod(type,"void Initial()",asMETHOD(T,Initial),asCALL_THISCALL);	 assert( r >= 0 );			
	r = engine->RegisterObjectMethod(type,"void AddCompositor(const string&in,int)",asMETHOD(T,AddCompositor),asCALL_THISCALL);	 assert( r >= 0 );			
	r = engine->RegisterObjectMethod(type,"void SetCompositor(const string&in,bool)",asMETHOD(T,SetCompositor),asCALL_THISCALL);	 assert( r >= 0 );			
}

REGISTER_TYPEMETHODS(ConfigDesc)
{
	
}

REGISTER_TYPEMETHODS(Overlay)
{
	r = engine->RegisterObjectMethod(type,"void show()",asMETHOD(T,show),asCALL_THISCALL);	 assert( r >= 0 );			
	r = engine->RegisterObjectMethod(type,"void hide()",asMETHOD(T,hide),asCALL_THISCALL);	 assert( r >= 0 );			
}

_NAMESPACE_END